package com.linx.common.web.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.linx.common.core.utils.HttpClientUtils;
import com.linx.common.core.utils.SpringUtils;
import com.linx.common.core.utils.StringUtils;
import com.linx.common.redis.utils.RedisUtils;
import com.linx.common.web.properties.WxProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
@Slf4j
public class WxMiniProgramUtils {


    private String appId;

    private String appSecret;


    public WxMiniProgramUtils() {
        WxProperties wxProperties = SpringUtils.getBean(WxProperties.class);
        appId = wxProperties.getAppid();
        appSecret = wxProperties.getSecret();
    }

    // 微信接口 URL
    private static final String WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    private static final String WX_JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session&grant_type" +
        "=authorization_code";
    private static final String WX_SUBSCRIBE_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send";
    private static final String WX_TEMPLAT_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate";
    private static final String WX_USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=";

    // 内存缓存 access_token (可替换为 Redis 等缓存工具)
    private static String cachedAccessToken = null;
    private static long tokenExpireTime = 0;


    /**
     * 获取微信 access_token（缓存机制）
     *
     * @return access_token
     * @throws Exception 异常
     */
    public String getAccessToken() throws Exception {
        String wxAccessToken = RedisUtils.getCacheObject("wxAccessToken");
        if (StringUtils.isBlank(wxAccessToken)) {
            // 构造请求参数
            Map<String, String> map = new HashMap<>();
            map.put("appid", appId);
            map.put("secret", appSecret);
            map.put("grant_type", "client_credential");
            // 调用微信接口
            String response = HttpClientUtils.sendGet(WX_ACCESS_TOKEN_URL, map);

            // 解析返回结果
            JSONObject jsonResponse = JSON.parseObject(response);
            if (jsonResponse.containsKey("access_token")) {
                cachedAccessToken = jsonResponse.getString("access_token");
                int expiresIn = jsonResponse.getIntValue("expires_in"); // 获取 expires_in 并转换为 int
                tokenExpireTime = System.currentTimeMillis() + (expiresIn * 1000L) - 60000;
                RedisUtils.setCacheObject("wxAccessToken", cachedAccessToken);
                RedisUtils.expire("wxAccessToken", tokenExpireTime);

                return cachedAccessToken;
            } else {
                throw new RuntimeException("获取微信access_token失败: " + jsonResponse);
            }
        } else {
            return wxAccessToken;
        }


    }

    //public String getAccessTokenV2() throws Exception {
    //
    //    appId="wxfd30b9b847002154";
    //    appSecret="f7ffd8db1523cb36b5060073df7a654a";
    //        // 构造请求参数
    //        Map<String, String> map = new HashMap<>();
    //        map.put("appid", appId);
    //        map.put("secret", appSecret);
    //         map.put("grant_type", "client_credential");
    //        // 调用微信接口
    //        String response = HttpClientUtils.sendGet(WX_ACCESS_TOKEN_URL, map);
    //
    //        // 解析返回结果
    //        JSONObject jsonResponse = JSON.parseObject(response);
    //        if (jsonResponse.containsKey("access_token")) {
    //            cachedAccessToken = jsonResponse.getString("access_token");
    //            return cachedAccessToken;
    //        } else {
    //            throw new RuntimeException("Failed to get access_token: " + response);
    //        }
    //
    //}


    /**
     * 登录凭证校验（code 换取 openId 和 sessionKey）
     *
     * @param code 小程序登录时获取的 code
     * @return 用户 openId 和 sessionKey
     * @throws Exception 异常
     */
    public Map<String, String> code2Session(String code) throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put("appid", appId);
        map.put("secret", appSecret);
        map.put("js_code", code);
        // 调用微信接口

        String response = HttpClientUtils.sendGet(WX_JSCODE2SESSION_URL, map);

        // 解析返回结果
        JSONObject jsonResponse = JSON.parseObject(response);
        if (jsonResponse.containsKey("openid") && jsonResponse.containsKey("session_key")) {
            Map<String, String> result = new HashMap<>();
            result.put("openId", jsonResponse.getString("openid"));
            result.put("sessionKey", jsonResponse.getString("session_key"));
            return result;
        } else {
            throw new RuntimeException("获取微信登录凭证校验失败: " + jsonResponse);
        }
    }


    /**
     * 发送订阅消息
     *
     * @throws Exception 异常
     */
    public List<String> gettemplate() throws Exception {
        String accessToken = getAccessToken();
        List<String> priTmplIdList = new ArrayList<>();
        // 请求 URL
        Map<String, String> map = new HashMap<>();
        map.put("access_token", accessToken);
        String result = "";

        try {
            result = HttpClientUtils.sendGet(WX_TEMPLAT_URL, map);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(result);
        // 发送 POST 请求
        JSONObject jsonResponse = JSON.parseObject(result);
        System.out.println(jsonResponse);
        // 解析返回的 JSON
        //根据微信接口返回的结果判断是否成功
        if (jsonResponse != null && jsonResponse.getInteger("errcode") == 0) {
            JSONArray templates = jsonResponse.getJSONArray("data");
            if (templates != null) {
                for (int i = 0; i < templates.size(); i++) {
                    JSONObject template = templates.getJSONObject(i);
                    String priTmplId = template.getString("priTmplId");
                    if (priTmplId != null) {
                        priTmplIdList.add(priTmplId);
                    }
                }
            }
        } else {
            throw new RuntimeException("获取微信推送模板失败: " + jsonResponse);
        }


        return priTmplIdList;

    }


    /**
     * 发送订阅消息
     *
     * @param openId     用户 openId
     * @param templateId 模板 ID
     * @param page       跳转页面路径
     * @param data       模板消息内容
     * @throws Exception 异常
     */
    public void sendSubscribeMessage(String openId, String templateId, String page, Map<String, Object> data) throws Exception {
        String accessToken = getAccessToken();

        // 请求 URL
        String url = WX_SUBSCRIBE_MESSAGE_URL + "?access_token=" + accessToken;

        String result = "";
        // 构建请求体
        JSONObject requestBody = new JSONObject();
        requestBody.put("touser", openId);
        requestBody.put("template_id", templateId);
        //requestBody.put("page", "index"); // 可以根据需要修改页面路径
        requestBody.put("miniprogram_state", "trial"); // 可以根据需要修改页面路径
        requestBody.put("lang", "zh_CN"); // 可以根据需要修改页面路径

        // 构建 data 字段
        JSONObject dataObject = new JSONObject();
        for (Map.Entry<String, Object> entry : data.entrySet()) {
            JSONObject valueObject = new JSONObject();
            valueObject.put("value", entry.getValue());
            dataObject.put(entry.getKey(), valueObject);
        }
        System.out.println(dataObject);
        requestBody.put("data", dataObject);

        try {
            result = HttpClientUtils.sendPost(url, requestBody.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(result);
        // 发送 POST 请求
        JSONObject jsonResponse = JSON.parseObject(result);
        System.out.println(jsonResponse);
        // 解析返回的 JSON
        //根据微信接口返回的结果判断是否成功

        if (jsonResponse.containsKey("errcode") && jsonResponse.getIntValue("errcode") != 0) {
            throw new RuntimeException("发送订阅消息失败: " + jsonResponse);
        }
    }


    public static void main(String[] args) {

        try {
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }
}
